package cn.chainco.cts.iserviceImpl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import cn.chainco.cts.idao.IPointDao;
import cn.chainco.cts.iservice.IPointManager;
import cn.chainco.cts.jdo.Country;
import cn.chainco.cts.jdo.Point;

public class PointManagerImpl extends CommonManagerImpl implements IPointManager{	
	private IPointDao pointDao;

	private Point dealPoint(Point p) {
		p.setName(p.getName().trim());
		p.setFullname(p.fullname());
		p.setFullnameNoSymbol(p.fullnameNoSymbol());
		return p;
	}
	
	private boolean verifyPoint(Point p) {
		if (p.getName().length() > 50) {
			return false;
		}
		if (p.getCountry() == null) {
			return false;
		}
		return true;
	}
	
	
	public void clearUpPoint() {
		List<Point> list = pointDao.updatePointByGroup();
		for (Point p : list) {
			p.setFullname(p.fullname());
			p.setFullnameNoSymbol(p.fullnameNoSymbolOnlyAirPort());
			pointDao.update(p);
		}
	}

	public boolean isPointCanDelete(Point point) {
		return pointDao.isPointCanDelete(point);
	}

	public int savePoint(Point point) {
		point = dealPoint(point);
		if (!verifyPoint(point)) {
			return 2;
		}

		List<Point> list = new ArrayList<Point>();
		
		list = pointDao.findPointDuplicate(point.getCountry(), point.getName(), point.getType(), point.getId());
		
		int result=0;
		if(list.size()>0 && Point.PLACE_TYPE_AIRPORT==point.getType()){
			for(Point p : list){
				if(p.getAirCode().equals(point.getAirCode())){
					result=1;
					break;
				}
			}
		}
		if(result==1){
			return 1;
		}
		else if (list.size() > 0 && point.getType()!=Point.PLACE_TYPE_AIRPORT) {
			return 1;
		} 
		else if (point.getId() == 0) {
			pointDao.save(point);
		} else {
			pointDao.update(point);
		}

		return 0;
	}
	
	/**
	 * 根据国家删除地名
	 */
	public void deletePointByCountry(Country country){
		pointDao.deletePointByCountry(country);
	}
	
	/**
	 * 此方法是将地点数据补充完整
	 */
	public List<Point> updatePointByGroup(){
		return pointDao.updatePointByGroup();
	}

	public void setPointDao(IPointDao pointDao) {
		this.pointDao = pointDao;
	}
	
	/**
	 * 关键词查询地点（2011.10.11以后适用）
	 * @param portType 0海港+内陆；1海港；2空港+内陆；3空港；4内陆
	 * @param keyword
	 * @return
	 */
	public List<Point> searchPoint(int portType, String keyword) {
		int records = 10;
		keyword = keyword.replaceAll(",", "").replaceAll(" ", "").replaceAll("[.]", "").replaceAll("-", "").replaceAll("'", "").replaceAll("[(]", "").replaceAll("[)]", "");
		keyword = keyword.trim();

		List<Point> list1 = new ArrayList<Point>();
		List<Point> list2 = new ArrayList<Point>();

		switch (portType) {
		case 0:
			list1 = pointDao.findPointByKeyword(true, Point.PLACE_TYPE_SEAPORT, keyword, records);
			int t0 = list1.size();
			if (t0 < records) {
				list2 = pointDao.findPointByKeyword(false, Point.PLACE_TYPE_SEAPORT, keyword, records - t0);
				list1.addAll(list2);
				int t02 = list2.size();
				if (t0 + t02 < records) {
					list2 = pointDao.findPointByKeyword(true, Point.PLACE_TYPE_INLAND, keyword, records - t0 - t02);
					list1.addAll(list2);
					int t03 = list2.size();
					if (t0 + t02 + t03 < records) {
						list1.addAll(pointDao.findPointByKeyword(false, Point.PLACE_TYPE_INLAND, keyword, records - t0 - t02 - t03));
					}
				}
			}
			break;
		case 1:
			list1 = pointDao.findPointByKeyword(true, Point.PLACE_TYPE_SEAPORT, keyword, records);
			int t1 = list1.size();
			if (t1 < records) {
				list1.addAll(pointDao.findPointByKeyword(false, Point.PLACE_TYPE_SEAPORT, keyword, records - t1));
			}
			break;
		case 2:
			list1 = pointDao.findPointByKeyword(true, Point.PLACE_TYPE_AIRPORT, keyword, records);
			int t2 = list1.size();
			if (t2 < records) {
				list2 = pointDao.findPointByKeyword(false, Point.PLACE_TYPE_AIRPORT, keyword, records - t2);
				list1.addAll(list2);
				int t22 = list2.size();
				if (t2 + t22 < records) {
					list2 = pointDao.findPointByKeyword(true, Point.PLACE_TYPE_INLAND, keyword, records - t2 - t22);
					list1.addAll(list2);
					int t23 = list2.size();
					if (t2 + t22 + t23 < records) {
						list1.addAll(pointDao.findPointByKeyword(false, Point.PLACE_TYPE_INLAND, keyword, records - t2 - t22 - t23));
					}
				}
			}
			break;
		case 3:
			list1 = pointDao.findPointByKeyword(true, Point.PLACE_TYPE_AIRPORT, keyword, records);
			int t3 = list1.size();
			if (t3 < records) {
				list1.addAll(pointDao.findPointByKeyword(false, Point.PLACE_TYPE_AIRPORT, keyword, records - t3));
			}
			break;
		default:
			list1 = pointDao.findPointByKeyword(true, Point.PLACE_TYPE_INLAND, keyword, records);
			int t4 = list1.size();
			if (t4 < records) {
				list1.addAll(pointDao.findPointByKeyword(false, Point.PLACE_TYPE_INLAND, keyword, records - t4));
			}
			break;
		}

		return list1;
	}
	
	/**
	 * 查询身边港口（2012.1.13以后适用）
	 * @param portType 0海港 1空港
	 * @return
	 */
	public List<Point> searchPointGEO(int portType, String lat, String lng) {
		List<Point> list1 = pointDao.findPortsByLat(portType, Double.valueOf(lat));
		List<Point> list2 = pointDao.findPortsByLng(portType, Double.valueOf(lng));
		List<Point> list = new ArrayList<Point>(list1);
		list.retainAll(list2);
		if (list.size() > 10) {
			list = list.subList(0, 10);
		}
		return sortPointGEO(list);
	}
	
	private List<Point> sortPointGEO(List<Point> list) {
		if (list.size() > 1) {
			List<Point> list1 = new ArrayList<Point>();
			List<Point> list2 = new ArrayList<Point>();
			for (Point p : list) {
				if (p.getBasePort() != null && p.getBasePort() == 1) {
					list1.add(p);
				} else {
					list2.add(p);
				}
			}
			list1.addAll(list2);
			return list1;
		} else {
			return list;
		}
	}
	
	/**
	 * 查询港口半径范围（2012.2.9以后适用）
	 * @param portType 0海港 1空港
	 * @return
	 */
	public List<Point> searchPointRadius(int portType, long pointId) {
		Point p = pointDao.findByPK(pointId);
		int raidus = 100 * 1000; // 100km
		List<Point> list = pointDao.findPortsByLatLng(portType, getAround(p.getLatitude(), p.getLongitude(), raidus));
		return list;
	}
	
	/**
	 * @param raidus (m)
	 * @return minLat,minLng,maxLat,maxLng
	 */
	private Double[] getAround(double lat, double lon, int raidus) {
		Double latitude = lat;
		Double longitude = lon;

		Double degree = (24901 * 1609) / 360.0;
		double raidusMile = raidus;

		Double dpmLat = 1 / degree;
		Double radiusLat = dpmLat * raidusMile;
		Double minLat = latitude - radiusLat;
		Double maxLat = latitude + radiusLat;

		Double mpdLng = degree * Math.cos(latitude * (Math.PI / 180));
		Double dpmLng = 1 / mpdLng;
		Double radiusLng = dpmLng * raidusMile;
		Double minLng = longitude - radiusLng;
		Double maxLng = longitude + radiusLng;
		return new Double[] { minLat, minLng, maxLat, maxLng };
	}
	
	/**
	 * 获取周边0所有海港/1所有空港
	 * @param point
	 * @return
	 */
	public String getNeighboringPorts(Point point, int type) {
		if (point.getLatitude() != null && point.getLongitude() != null && point.getZoomLevel() != null) {
			String str = point.getId() + "@" + point.getLatitude() + "@" + point.getLongitude() + "@"
					+ dealFullName(point.fullname(), type) + "@" + mapIconName(point.getType(), point.getBasePort());
			List<Point> list = pointDao.findNeighboringPorts(point.getId(), type);
			for (Point p : list) {
				str += ("#" + p.getId() + "@" + p.getLatitude() + "@" + p.getLongitude() + "@" 
						+ dealFullName(p.fullname(), type))	+ "@" + mapIconName(p.getType(), p.getBasePort());
			}
			return str;
		} else {
			return "";
		}
	}
	
	public String getNoLatLngPoints() {
//		String str = "";
//		List<Point> list = pointDao.findNoLatLngPoints();
//		
//		for (Point p : list) {
//			str += (p.getId() + "@" + p.getFullname().replaceAll("'", " ") + "#");
//		}
//		return str.substring(0, str.length() - 1);
		return null;
	}
	
	private String mapIconName(int type, Integer basePort) {
		String name = "map_p" + type;
		if (type <= 1 && basePort != null && basePort == 1) {
			name += "1";
		} else {
			name += "0";
		}
		name += ".png";
		return name;
	}

	private String dealFullName(String fullname, int type) {
		if (type <= 1) {
			return fullname.trim().toUpperCase().replaceAll("'", " ");
		}
		return fullname.trim().replaceAll("'", " ");
	}

//	private Double[] getPointRadius(Double lat, Double lng, int raidus) {
//		Double degree = (24901 * 1609) / 360.0;
//		double raidusMile = raidus;
//
//		Double dpmLat = 1 / degree;
//		Double radiusLat = dpmLat * raidusMile;
//		Double minLat = lat - radiusLat;
//		Double maxLat = lat + radiusLat;
//
//		Double mpdLng = degree * Math.cos(lat * (Math.PI / 180));
//		Double dpmLng = 1 / mpdLng;
//		Double radiusLng = dpmLng * raidusMile;
//		Double minLng = lng - radiusLng;
//		Double maxLng = lng + radiusLng;
//		return new Double[] { minLat, maxLat, minLng, maxLng };
//	}

	/**
	 * 处理地点的分组标签（根据逗号分隔）
	 */
	public Set<String> getGroupNameList(){
		List<String> list=pointDao.findPointGroupNameByString();
		Set<String> set = new HashSet<String>();
		for (String s : list) {
			String strs[]=s.split(",");
			for (String str : strs) {
				set.add(str);
			}
		}
		return set;
	}
	
	/**
	 * 修改地点的分组状态
	 * @param id
	 */
	public void updatePointGroup(String idStr){
		pointDao.updatePointGroup(idStr);
	}
	
	/**
	 * 修改地点的分组状态
	 * @param id
	 */
	public void updatePointGroup(Long id){
		pointDao.updatePointGroup(id);
	}
}
